//
//  CImageDownloadedManager.m
//
//
//  Created by fanty on 13-4-22.
//  Copyright (c) 2013年 fanty. All rights reserved.
//

#import "CImageDownloadedManager.h"
#import <chameleon-ios-sdk/Library/ChamleonHTTPRequest.h>

#define  IMAGE_HTTP_TIME_OUT     8
static CImageDownloadedManager* instance=nil;

@interface CImageDownloadModel:NSObject{
    NSTimer* timer;
}

@property(nonatomic,assign) CGSize size;
@property(nonatomic,strong) NSString* url;
@property(nonatomic,strong) UIImage* image;
@property(nonatomic,assign) int retainImageCount;
@property(nonatomic,assign) BOOL downloaded;

-(void)checkFileAndDownload;
-(void)delayLoadImage;
-(void)checkFile;
-(UIImage*)imageWithThumbnail:(UIImage *)_image size:(CGSize)thumbSize;
-(NSString*)imagePath;
@end

@implementation CImageDownloadModel

@synthesize url;
@synthesize size;
@synthesize image;
@synthesize retainImageCount;
@synthesize downloaded;

-(id)init{
    self=[super init];
    self.size=CGSizeMake(150.0f, 150.0f);
    return self;
}

-(void)delayLoadImage{
    [timer invalidate];
    timer=nil;
    self.downloaded=YES;
    
    if(image==nil){
        retainImageCount=0;
        [self checkFile];
    }
    [[NSNotificationCenter defaultCenter] postNotificationName:NotificationImageLoadingFinish object:self.url];
    
}

-(NSString*)imagePath{
    NSURL* nsUrl=[NSURL URLWithString:self.url];
    NSString* path=[[CImageDownloadedManager sharedInstance].saveImagePath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@_%@",[nsUrl host],[[nsUrl path] stringByReplacingOccurrencesOfString:@"/" withString:@""] ]  ];

    return path;
}

-(void)checkFileAndDownload{
    NSURL* nsUrl=[NSURL URLWithString:self.url];
    NSString* path=[self imagePath];
    
    if([[NSFileManager defaultManager] fileExistsAtPath:path]){
        //delay to call
        if(timer==nil)
            timer=[NSTimer scheduledTimerWithTimeInterval:0.3f target:self selector:@selector(delayLoadImage) userInfo:nil repeats:NO];
        
    }
    else{
        ChamleonHTTPRequest* request=[[CImageDownloadedManager sharedInstance] imageDownloadRequest:nsUrl];
        [request setDownloadDestinationPath :path];
        __block CImageDownloadModel* objSelf=self;
        [request setCompletionBlock:^{
            objSelf.downloaded=YES;
            //notification
            [[NSNotificationCenter defaultCenter] postNotificationName:NotificationImageLoadingFinish object:self.url];
        }];
        [request setFailedBlock:^{
            objSelf.downloaded=YES;
            objSelf.retainImageCount=0;
            [[NSNotificationCenter defaultCenter] postNotificationName:NotificationImageLoadingFinish object:self.url];
        }];
        [request startAsynchronous ];
    }
    
}

-(void)checkFile{
    if(self.image!=nil)return;
    NSString* path=[self imagePath];

    @autoreleasepool {
        UIImage* img=[[UIImage alloc] initWithData:[NSData dataWithContentsOfFile:path]];
        self.image=img;
        
        if(self.image==nil){
            [[NSFileManager defaultManager] removeItemAtPath:path error:nil];
            retainImageCount=0;
        }
        else{
            if(size.width>0 && size.height>0){
                CGSize _size=self.image.size;
                if((_size.width>size.width && _size.height>size.height) || (_size.width<60.0f && _size.height<60.0f)){
                    self.image=[self imageWithThumbnail:self.image size:self.size];
                }
            }
            else{
                size=CGSizeZero;
            }
        }
        
    }
    
}

-(UIImage*)imageWithThumbnail:(UIImage *)_image size:(CGSize)thumbSize{
    
    CGSize imageSize = _image.size;
    
    CGFloat width = imageSize.width;
    
    CGFloat height = imageSize.height;
    
    
    CGFloat scaleFactor = 0.0;
    
    CGPoint thumbPoint = CGPointMake(0.0,0.0);
    CGFloat widthFactor = thumbSize.width / width;
    
    CGFloat heightFactor = thumbSize.height / height;
    if (widthFactor > heightFactor)  {
        scaleFactor = widthFactor;
    }
    
    else {
        
        scaleFactor = heightFactor;
        
    }
    
    CGFloat scaledWidth  = width * scaleFactor;
    
    CGFloat scaledHeight = height * scaleFactor;
    
    if (widthFactor > heightFactor){
        
        thumbPoint.y = (thumbSize.height - scaledHeight) * 0.5;
    }
    
    else if (widthFactor < heightFactor){
        thumbPoint.x = (thumbSize.width - scaledWidth) * 0.5;
    }
    UIGraphicsBeginImageContext(thumbSize);
    
    CGRect thumbRect = CGRectZero;
    
    thumbRect.origin = thumbPoint;
    
    thumbRect.size.width  = scaledWidth;
    
    thumbRect.size.height = scaledHeight;
    
    [_image drawInRect:thumbRect];
    
    
    
    UIImage *thumbImage = UIGraphicsGetImageFromCurrentImageContext();
    
    UIGraphicsEndImageContext();
    
    return thumbImage;
}


-(void)setRetainCount:(int)value{
    if(value<1)value=0;
    retainImageCount=value;
    if(retainImageCount<1){
        self.image=nil;
    }
}

@end



@implementation CImageDownloadedManager
@synthesize saveImagePath;
@synthesize downloadedImageTimeout;
@synthesize delegate;

+(CImageDownloadedManager*)sharedInstance{
    if(instance==nil)
        instance=[[CImageDownloadedManager alloc] init];
    return instance;
}

-(id)init{
    self=[super init];
    if(self){
        NSString* imageRoot=[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0];

        imageRoot=[imageRoot stringByAppendingPathComponent:@"images"];
        NSFileManager* fileManager=[NSFileManager defaultManager];
        if(![fileManager fileExistsAtPath:imageRoot]){
            [fileManager createDirectoryAtPath:imageRoot withIntermediateDirectories:YES attributes:nil error:nil];
        }
        
        self.saveImagePath=imageRoot;

        self.downloadedImageTimeout=IMAGE_HTTP_TIME_OUT;
        list=[[NSMutableArray alloc] initWithCapacity:3];
    }
    return self;
}




-(UIImage*)appendUrl:(NSString*)url size:(CGSize)size{
    if([url length]<1)return nil;
    
    for(CImageDownloadModel* model in list){
        if([model.url isEqualToString:url] && model.size.width==size.width && model.size.height==size.height){
            if(model.image!=nil){
                model.retainImageCount++;
                return model.image;
            }
            else{
                [model checkFile];
                if(model.image!=nil){
                    model.retainImageCount++;
                    return model.image;
                }
            }
            if(model.downloaded && model.image==nil){
                model.downloaded=NO;
                [model checkFileAndDownload];
                
            }
            return nil;
        }
    }
    CImageDownloadModel* model =[[CImageDownloadModel alloc] init];
    model.size=size;
    model.url=url;
    model.retainImageCount=0;
    [model checkFileAndDownload];
    [list addObject:model];
    return nil;
}


-(UIImage*)get:(NSString*)url size:(CGSize)size{
    for(CImageDownloadModel* model in list){
        if([model.url isEqualToString:url] && model.size.width==size.width && model.size.height==size.height){
            [model checkFile];
            if(model.image!=nil)
                model.retainImageCount++;
            return model.image;
        }
    }
    return nil;
}

-(void)remove:(NSString*)url size:(CGSize)size{
    if([url length]<1)return;
    for(CImageDownloadModel* model in list){
        if([model.url isEqualToString:url] && model.size.width==size.width && model.size.height==size.height){
            if(model.image!=nil)
                model.retainImageCount--;
            break;
        }
    }
    
}

-(BOOL)checkImageIsDownloadedByUrl:(NSString*)url size:(CGSize)size{
    if([url length]<1)return YES;
    for(CImageDownloadModel* model in list){
        if([model.url isEqualToString:url] && model.size.width==size.width && model.size.height==size.height){
            return model.downloaded;
        }
    }
    return YES;
}

-(ChamleonHTTPRequest*)imageDownloadRequest:(NSURL*)url{
    ChamleonHTTPRequest* request=nil;
    if([self.delegate respondsToSelector:@selector(imageDownloadRequest:)]){
        request=[self.delegate imageDownloadRequest:url];
    }
    if(request==nil){
        request=[ChamleonHTTPRequest requestWithURL:url];
        request.timeOutSeconds=self.downloadedImageTimeout;
        request.persistentConnectionTimeoutSeconds=self.downloadedImageTimeout;
    }
    return request;
}


@end
